home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / MATH / EJCPLX01 / TRIG.PAS < prev    next >
Pascal/Delphi Source File  |  1988-02-02  |  15KB  |  488 lines

  1. {$R-,S-}
  2. unit Trig;
  3.  
  4. (*  TRIG  -  Supplies missing trigonometric functions for Turbo Pascal 4.0
  5.  *           Also provides hyperbolic, logarithmic, power, and root functions.
  6.  *           All trig functions accessible by radians, decimal degrees,
  7.  *           degrees-minutes-seconds, and a global DegreeType.  Conversions
  8.  *           between these are supplied.
  9.  *
  10.  *  Written November 23, 1987 by Hugo Hemmerich, Refined Technologies.
  11.  *  All code granted to the public domain.
  12.  *
  13.  *  Questions and comments to CompuServe account number 72376,3505
  14.  *)
  15.  
  16. interface
  17.  
  18. type
  19.   DegreeType =  record
  20.                   Degrees, Minutes, Seconds : real;
  21.                 end;
  22. const
  23.   Infinity = 9.9999999999E+37;
  24.  
  25. {  Radians  }
  26. { sin, cos, and arctan are predefined }
  27.  
  28. function Tan( Radians : real ) : real;
  29. function ArcSin( InValue : real ) : real;
  30. function ArcCos( InValue : real ) : real;
  31.  
  32. {  Degrees, expressed as a real number  }
  33.  
  34. function DegreesToRadians( Degrees : real ) : real;
  35. function RadiansToDegrees( Radians : real ) : real;
  36. function Sin_Degree( Degrees : real ) : real;
  37. function Cos_Degree( Degrees : real ) : real;
  38. function Tan_Degree( Degrees : real ) : real;
  39. function ArcSin_Degree( Degrees : real ) : real;
  40. function ArcCos_Degree( Degrees : real ) : real;
  41. function ArcTan_Degree( Degrees : real ) : real;
  42.  
  43. {  Degrees, in Degrees, Minutes, and Seconds, as real numbers  }
  44.  
  45. function DegreePartsToDegrees( Degrees, Minutes, Seconds : real ) : real;
  46. function DegreePartsToRadians( Degrees, Minutes, Seconds : real ) : real;
  47. procedure DegreesToDegreeParts( DegreesIn : real;
  48.                                 var Degrees, Minutes, Seconds : real );
  49. procedure RadiansToDegreeParts( Radians : real;
  50.                                 var Degrees, Minutes, Seconds : real );
  51. function Sin_DegreeParts( Degrees, Minutes, Seconds : real ) : real;
  52. function Cos_DegreeParts( Degrees, Minutes, Seconds : real ) : real;
  53. function Tan_DegreeParts( Degrees, Minutes, Seconds : real ) : real;
  54. function ArcSin_DegreeParts( Degrees, Minutes, Seconds : real ) : real;
  55. function ArcCos_DegreeParts( Degrees, Minutes, Seconds : real ) : real;
  56. function ArcTan_DegreeParts( Degrees, Minutes, Seconds : real ) : real;
  57.  
  58. {  Degrees, expressed as DegreeType ( reals in record ) }
  59.  
  60. function DegreeTypeToDegrees( DegreeVar : DegreeType ) : real;
  61. function DegreeTypeToRadians( DegreeVar : DegreeType ) : real;
  62. procedure DegreeTypeToDegreeParts( DegreeVar : DegreeType;
  63.                                    var Degrees, Minutes, Seconds : real );
  64. procedure DegreesToDegreeType( Degrees : real; var DegreeVar : DegreeType );
  65. procedure RadiansToDegreeType( Radians : real; var DegreeVar : DegreeType );
  66. procedure DegreePartsToDegreeType( Degrees, Minutes, Seconds : real;
  67.                                    var DegreeVar : DegreeType );
  68. function Sin_DegreeType( DegreeVar : DegreeType ) : real;
  69. function Cos_DegreeType( DegreeVar : DegreeType ) : real;
  70. function Tan_DegreeType( DegreeVar : DegreeType ) : real;
  71. function ArcSin_DegreeType( DegreeVar : DegreeType ) : real;
  72. function ArcCos_DegreeType( DegreeVar : DegreeType ) : real;
  73. function ArcTan_DegreeType( DegreeVar : DegreeType ) : real;
  74.  
  75. {  Hyperbolic functions  }
  76.  
  77. function Sinh( Invalue : real ) : real;
  78. function Cosh( Invalue : real ) : real;
  79. function Tanh( Invalue : real ) : real;
  80. function Coth( Invalue : real ) : real;
  81. function Sech( Invalue : real ) : real;
  82. function Csch( Invalue : real ) : real;
  83. function ArcSinh( Invalue : real ) : real;
  84. function ArcCosh( Invalue : real ) : real;
  85. function ArcTanh( Invalue : real ) : real;
  86. function ArcCoth( Invalue : real ) : real;
  87. function ArcSech( Invalue : real ) : real;
  88. function ArcCsch( Invalue : real ) : real;
  89.  
  90. {  Logarithms, Powers, and Roots  }
  91.  
  92. { e to the x  is  exp() }
  93. { natural log is  ln()  }
  94. function Log10( InNumber : real ) : real;
  95. function Log( Base, InNumber : real ) : real;  { log of any base }
  96. function Power( InNumber, Exponent : real ) : real;
  97. function Root( InNumber, TheRoot : real ) : real;
  98.  
  99. {----------------------------------------------------------------------}
  100. implementation
  101.  
  102. const
  103.   RadiansPerDegree =  0.017453292520;
  104.   DegreesPerRadian = 57.295779513;
  105.   MinutesPerDegree =   60.0;
  106.   SecondsPerDegree = 3600.0;
  107.   SecondsPerMinute = 60.0;
  108.   LnOf10 = 2.3025850930;
  109.  
  110. {-----------}
  111. {  Radians  }
  112. {-----------}
  113.  
  114. { sin, cos, and arctan are predefined }
  115.  
  116. function Tan { ( Radians : real ) : real };
  117.   { note: returns Infinity where appropriate }
  118.   var
  119.     CosineVal : real;
  120.     TangentVal : real;
  121.   begin
  122.   CosineVal := cos( Radians );
  123.   if CosineVal = 0.0 then
  124.     Tan := Infinity
  125.   else
  126.     begin
  127.     TangentVal := sin( Radians ) / CosineVal;
  128.     if ( TangentVal < -Infinity ) or ( TangentVal > Infinity ) then
  129.       Tan := Infinity
  130.     else
  131.       Tan := TangentVal;
  132.     end;
  133.   end;
  134.  
  135. function ArcSin{ ( InValue : real ) : real };
  136.   { notes: 1) exceeding input range of -1 through +1 will cause runtime error }
  137.   {        2) only returns principal values                                   }
  138.   {             ( -pi/2 through pi/2 radians ) ( -90 through +90 degrees )    }
  139.   begin
  140.   if abs( InValue ) = 1.0 then
  141.     ArcSin := pi / 2.0
  142.   else
  143.     ArcSin := arctan( InValue / sqrt( 1 - InValue * InValue ) );
  144.   end;
  145.  
  146. function ArcCos{ ( InValue : real ) : real };
  147.   { notes: 1) exceeding input range of -1 through +1 will cause runtime error }
  148.   {        2) only returns principal values                                   }
  149.   {             ( 0 through pi radians ) ( 0 through +180 degrees )           }
  150.   var
  151.     Result : real;
  152.   begin
  153.   if InValue = 0.0 then
  154.     ArcCos := pi / 2.0
  155.   else
  156.     begin
  157.     Result := arctan( sqrt( 1 - InValue * InValue ) / InValue );
  158.     if InValue < 0.0 then
  159.       ArcCos := Result + pi
  160.     else
  161.       ArcCos := Result;
  162.     end;
  163.   end;
  164.  
  165. {---------------------------------------}
  166. {  Degrees, expressed as a real number  }
  167. {---------------------------------------}
  168.  
  169. function DegreesToRadians{ ( Degrees : real ) : real };
  170.   begin
  171.   DegreesToRadians := Degrees * RadiansPerDegree;
  172.   end;
  173.  
  174. function RadiansToDegrees{ ( Radians : real ) : real };
  175.   begin
  176.   RadiansToDegrees := Radians * DegreesPerRadian;
  177.   end;
  178.  
  179. function Sin_Degree{ ( Degrees : real ) : real };
  180.   begin
  181.   Sin_Degree := sin( DegreesToRadians( Degrees ) );
  182.   end;
  183.  
  184. function Cos_Degree{ ( Degrees : real ) : real };
  185.   begin
  186.   Cos_Degree := cos( DegreesToRadians( Degrees ) );
  187.   end;
  188.  
  189. function Tan_Degree{ ( Degrees : real ) : real };
  190.   begin
  191.   Tan_Degree := Tan( DegreesToRadians( Degrees ) );
  192.   end;
  193.  
  194. function ArcSin_Degree{ ( Degrees : real ) : real };
  195.   begin
  196.   ArcSin_Degree := ArcSin( DegreesToRadians( Degrees ) );
  197.   end;
  198.  
  199. function ArcCos_Degree{ ( Degrees : real ) : real };
  200.   begin
  201.   ArcCos_Degree := ArcCos( DegreesToRadians( Degrees ) );
  202.   end;
  203.  
  204. function ArcTan_Degree{ ( Degrees : real ) : real };
  205.   begin
  206.   ArcTan_Degree := arctan( DegreesToRadians( Degrees ) );
  207.   end;
  208.  
  209. {--------------------------------------------------------------}
  210. {  Degrees, in Degrees, Minutes, and Seconds, as real numbers  }
  211. {--------------------------------------------------------------}
  212.  
  213. function DegreePartsToDegrees{ ( Degrees, Minutes, Seconds : real ) : real };
  214.   begin
  215.   DegreePartsToDegrees := Degrees + ( Minutes / MinutesPerDegree ) +
  216.                                        ( Seconds / SecondsPerDegree );
  217.   end;
  218.  
  219. function DegreePartsToRadians{ ( Degrees, Minutes, Seconds : real ) : real };
  220.   begin
  221.   DegreePartsToRadians := DegreesToRadians( DegreePartsToDegrees( Degrees,
  222.                                                         Minutes, Seconds ) );
  223.   end;
  224.  
  225. procedure DegreesToDegreeParts{ ( DegreesIn : real;
  226.                                   var Degrees, Minutes, Seconds : real ) };
  227.   begin
  228.   Degrees := int( DegreesIn );
  229.   Minutes := ( DegreesIn - Degrees ) * MinutesPerDegree;
  230.   Seconds := frac( Minutes );
  231.   Minutes := int( Minutes );
  232.   Seconds := Seconds * SecondsPerMinute;
  233.   end;
  234.  
  235. procedure RadiansToDegreeParts{ ( Radians : real;
  236.                                   var Degrees, Minutes, Seconds : real ) };
  237.   begin
  238.   DegreesToDegreeParts( RadiansToDegrees( Radians ),
  239.                           Degrees, Minutes, Seconds );
  240.   end;
  241.  
  242. function Sin_DegreeParts{ ( Degrees, Minutes, Seconds : real ) : real };
  243.   begin
  244.   Sin_DegreeParts := sin( DegreePartsToRadians( Degrees, Minutes, Seconds ) );
  245.   end;
  246.  
  247. function Cos_DegreeParts{ ( Degrees, Minutes, Seconds : real ) : real };
  248.   begin
  249.   Cos_DegreeParts := cos( DegreePartsToRadians( Degrees, Minutes, Seconds ) );
  250.   end;
  251.  
  252. function Tan_DegreeParts{ ( Degrees, Minutes, Seconds : real ) : real };
  253.   begin
  254.   Tan_DegreeParts := Tan( DegreePartsToRadians( Degrees, Minutes, Seconds ) );
  255.   end;
  256.  
  257. function ArcSin_DegreeParts{ ( Degrees, Minutes, Seconds : real ) : real };
  258.   begin
  259.   ArcSin_DegreeParts := ArcSin( DegreePartsToRadians( Degrees,
  260.                                                       Minutes, Seconds ) );
  261.   end;
  262.  
  263. function ArcCos_DegreeParts{ ( Degrees, Minutes, Seconds : real ) : real };
  264.   begin
  265.   ArcCos_DegreeParts := ArcCos( DegreePartsToRadians( Degrees,
  266.                                                       Minutes, Seconds ) );
  267.   end;
  268.  
  269. function ArcTan_DegreeParts{ ( Degrees, Minutes, Seconds : real ) : real };
  270.   begin
  271.   ArcTan_DegreeParts := arctan( DegreePartsToRadians( Degrees,
  272.                                                       Minutes, Seconds ) );
  273.   end;
  274.  
  275. {-------------------------------------------------------}
  276. {  Degrees, expressed as DegreeType ( reals in record ) }
  277. {-------------------------------------------------------}
  278.  
  279. function DegreeTypeToDegrees{ ( DegreeVar : DegreeType ) : real };
  280.   begin
  281.   DegreeTypeToDegrees := DegreePartsToDegrees( DegreeVar.Degrees,
  282.                                        DegreeVar.Minutes, DegreeVar.Seconds );
  283.   end;
  284.  
  285. function DegreeTypeToRadians{ ( DegreeVar : DegreeType ) : real };
  286.   begin
  287.   DegreeTypeToRadians := DegreesToRadians( DegreeTypeToDegrees( DegreeVar ) );
  288.   end;
  289.  
  290. procedure DegreeTypeToDegreeParts{ ( DegreeVar : DegreeType;
  291.                                      var Degrees, Minutes, Seconds : real ) };
  292.   begin
  293.   Degrees := DegreeVar.Degrees;
  294.   Minutes := DegreeVar.Minutes;
  295.   Seconds := DegreeVar.Seconds;
  296.   end;
  297.  
  298. procedure DegreesToDegreeType{ ( Degrees : real; var DegreeVar : DegreeType )};
  299.   begin
  300.   DegreesToDegreeParts( Degrees, DegreeVar.Degrees,
  301.                         DegreeVar.Minutes, DegreeVar.Seconds );
  302.   end;
  303.  
  304. procedure RadiansToDegreeType{ ( Radians : real; var DegreeVar : DegreeType )};
  305.   begin
  306.   DegreesToDegreeParts( RadiansToDegrees( Radians ), DegreeVar.Degrees,
  307.                         DegreeVar.Minutes, DegreeVar.Seconds );
  308.   end;
  309.  
  310. procedure DegreePartsToDegreeType{ ( Degrees, Minutes, Seconds : real;
  311.                                      var DegreeVar : DegreeType ) };
  312.   begin
  313.   DegreeVar.Degrees := Degrees;
  314.   DegreeVar.Minutes := Minutes;
  315.   DegreeVar.Seconds := Seconds;
  316.   end;
  317.  
  318. function Sin_DegreeType{ ( DegreeVar : DegreeType ) : real };
  319.   begin
  320.   Sin_DegreeType := sin( DegreeTypeToRadians( DegreeVar ) );
  321.   end;
  322.  
  323. function Cos_DegreeType{ ( DegreeVar : DegreeType ) : real };
  324.   begin
  325.   Cos_DegreeType := cos( DegreeTypeToRadians( DegreeVar ) );
  326.   end;
  327.  
  328. function Tan_DegreeType{ ( DegreeVar : DegreeType ) : real };
  329.   begin
  330.   Tan_DegreeType := Tan( DegreeTypeToRadians( DegreeVar ) );
  331.   end;
  332.  
  333. function ArcSin_DegreeType{ ( DegreeVar : DegreeType ) : real };
  334.   begin
  335.   ArcSin_DegreeType := ArcSin( DegreeTypeToRadians( DegreeVar ) );
  336.   end;
  337.  
  338. function ArcCos_DegreeType{ ( DegreeVar : DegreeType ) : real };
  339.   begin
  340.   ArcCos_DegreeType := ArcCos( DegreeTypeToRadians( DegreeVar ) );
  341.   end;
  342.  
  343. function ArcTan_DegreeType{ ( DegreeVar : DegreeType ) : real };
  344.   begin
  345.   ArcTan_DegreeType := arctan( DegreeTypeToRadians( DegreeVar ) );
  346.   end;
  347.  
  348. {------------------------}
  349. {  Hyperbolic functions  }
  350. {------------------------}
  351.  
  352. function Sinh{ ( Invalue : real ) : real };
  353.   const
  354.     MaxValue = 88.029691931;  { exceeds standard turbo precision }
  355.   var
  356.     Sign : real;
  357.   begin
  358.   Sign := 1.0;
  359.   if Invalue < 0 then
  360.     begin
  361.     Sign := -1.0;
  362.     Invalue := -Invalue;
  363.     end;
  364.   if Invalue > MaxValue then
  365.     Sinh := Infinity
  366.   else
  367.     Sinh := ( exp( Invalue ) - exp( -Invalue ) ) / 2.0 * Sign;
  368.   end;
  369.  
  370. function Cosh{ ( Invalue : real ) : real };
  371.   const
  372.     MaxValue = 88.029691931;  { exceeds standard turbo precision }
  373.   begin
  374.   Invalue := abs( Invalue );
  375.   if Invalue > MaxValue then
  376.     Cosh := Infinity
  377.   else
  378.     Cosh := ( exp( Invalue ) + exp( -Invalue ) ) / 2.0;
  379.   end;
  380.  
  381. function Tanh{ ( Invalue : real ) : real };
  382.   begin
  383.   Tanh := Sinh( Invalue ) / Cosh( Invalue );
  384.   end;
  385.  
  386. function Coth{ ( Invalue : real ) : real };
  387.   begin
  388.   Coth := Cosh( Invalue ) / Sinh( Invalue );
  389.   end;
  390.  
  391. function Sech{ ( Invalue : real ) : real };
  392.   begin
  393.   Sech := 1.0 / Cosh( Invalue );
  394.   end;
  395.  
  396. function Csch{ ( Invalue : real ) : real };
  397.   begin
  398.   Csch := 1.0 / Sinh( Invalue );
  399.   end;
  400.  
  401. function ArcSinh{ ( Invalue : real ) : real };
  402.   var
  403.     Sign : real;
  404.   begin
  405.   Sign := 1.0;
  406.   if Invalue < 0 then
  407.     begin
  408.     Sign := -1.0;
  409.     Invalue := -Invalue;
  410.     end;
  411.   ArcSinh := ln( Invalue + sqrt( Invalue*Invalue + 1 ) ) * Sign;
  412.   end;
  413.  
  414. function ArcCosh{ ( Invalue : real ) : real };
  415.   var
  416.     Sign : real;
  417.   begin
  418.   Sign := 1.0;
  419.   if Invalue < 0 then
  420.     begin
  421.     Sign := -1.0;
  422.     Invalue := -Invalue;
  423.     end;
  424.   ArcCosh := ln( Invalue + sqrt( Invalue*Invalue - 1 ) ) * Sign;
  425.   end;
  426.  
  427. function ArcTanh{ ( Invalue : real ) : real };
  428.   var
  429.     Sign : real;
  430.   begin
  431.   Sign := 1.0;
  432.   if Invalue < 0 then
  433.     begin
  434.     Sign := -1.0;
  435.     Invalue := -Invalue;
  436.     end;
  437.   ArcTanh := ln( ( 1 + Invalue ) / ( 1 - Invalue ) ) / 2.0 * Sign;
  438.   end;
  439.  
  440. function ArcCoth{ ( Invalue : real ) : real };
  441.   begin
  442.   ArcCoth := ArcTanh( 1.0 / Invalue );
  443.   end;
  444.  
  445. function ArcSech{ ( Invalue : real ) : real };
  446.   begin
  447.   ArcSech := ArcCosh( 1.0 / Invalue );
  448.   end;
  449.  
  450. function ArcCsch{ ( Invalue : real ) : real };
  451.   begin
  452.   ArcCsch := ArcSinh( 1.0 / Invalue );
  453.   end;
  454.  
  455. {---------------------------------}
  456. {  Logarithms, Powers, and Roots  }
  457. {---------------------------------}
  458.  
  459. { e to the x  is  exp() }
  460. { natural log is  ln()  }
  461.  
  462. function Log10{ ( InNumber : real ) : real };
  463.   begin
  464.   Log10 := ln( InNumber ) / LnOf10;
  465.   end;
  466.  
  467. function Log{ ( Base, InNumber : real ) : real };  { log of any base }
  468.   begin
  469.   Log := ln( InNumber ) / ln( Base );
  470.   end;
  471.  
  472. function Power{ ( InNumber, Exponent : real ) : real };
  473.   begin
  474.   if InNumber > 0.0 then
  475.     Power := exp( Exponent * ln( InNumber ) )
  476.   else if InNumber = 0.0 then
  477.     Power := 1.0
  478.   else { force runtime error }
  479.     Power := InNumber / 0.0;
  480.   end;
  481.  
  482. function Root{ ( InNumber, TheRoot : real ) : real };
  483.   begin
  484.   Root := Power( InNumber, ( 1.0 / TheRoot ) );
  485.   end;
  486.  
  487. end. { unit Trig }
  488.